#ifndef MAP_H
#define MAP_H


#include "samplerglobals.h"
#include"sampler/polyphonychannel.h"
#include <QQueue>

using namespace sampler;
class SampleRecord;
class PolyphonyChannel;

class Map
{
    friend class Sampler;
public:
    Map(size_t bufsize);
    ~Map();

    struct MapElement {
        MapElement() : sample(NULL), polyphonyChannel(NULL){}
        SampleRecord* sample;
        PolyphonyChannel* polyphonyChannel;
    };

    inline MapElement & element(char note) {
        return note > 0 ? map_[(int)note] : map_[0];
    }

    inline PolyphonyChannel* getFreeChannel(){
        PolyphonyChannel* pc = NULL;
        if (! freeChannels_.isEmpty())
        {
            pc = freeChannels_.takeLast();
            gl::log("PCH: get new free channel");
        }
        else{
            pc = currentChannels_.dequeue();
            gl::log("PCH: reuse channel");
        }
        currentChannels_.enqueue(pc);
        return pc;
    };

    inline void setChannelFree(PolyphonyChannel* channel){
        gl::log("SMP: freeng channel for note %1", channel->note());
        currentChannels_.removeAll(channel);
        freeChannels_.append(channel);
        map_[channel->note()].polyphonyChannel = NULL;
    }

protected:
    const SampleRecord * loadSample(const Note & bottomLeft,
                                    const Note & upperRight,
                                    char root_unused, const QString & fileName);

    MapElement map_[k_notes_count];

    QList<SampleRecord*> sample_table_;
    QQueue<PolyphonyChannel*> currentChannels_;
    QList<PolyphonyChannel*> freeChannels_;

    //    struct State;
    //    QList<State*> state_table_;


};

#endif // MAP_H
